

/******************************************************************************
 *
 *
 * File:	USB_GUI_0100_M52259DEMO.c
 *
 *
 ******************************************************************************/
 
 /*****************************************************************************
  *
  *
  * This is a demonstration program showing USB communications using
  *		usb_logger.c. For a description of its operation see
  *		USB_GUI_0100 rev100.doc.
  *
  *
  *****************************************************************************/ 

#include <mqx.h>
#include <bsp.h>
#include "main.h"
#include <usb_logger.h>
#include <USB_GUI_0100_M52259DEMO.h>


/*******************************************************************************
 *
 * Constants
 *
 ******************************************************************************/
 #define MY_TRIGGER_0 ADC_TRIGGER_1
 #define MY_TRIGGER_1 ADC_TRIGGER_2



/*******************************************************************************
 *
 *	GLOBAL VARIABLES
 *
 *******************************************************************************/
  uint_8 Data[15000];	 	//15K butes of RAM reserved for data
  uint_8 Putter = 0;		//Data vector putter
  uint_8 Getter = 0;		//Data vector getter
  uint_8 i = 0;				//General loop index  
  uint_8 Data_Length = 0;	//Data vector length
  uint_8 LChase = 0;				//Led Chaser mode select (0 = off, 1 = on)
  
  

 /*************************** INITIALIZATIONS *********************************
 
 
  *		Control structures for EP1 & EP3 OUT (receive) packet transactions.
  *		These are declared in usb_logger.c
  */
 extern EP_RX_CTRL ep1_rx_ctrl;
 extern EP_RX_CTRL ep3_rx_ctrl;
 
 /* Logger Global Variable Structure. */
 extern LOGGER_GLOBAL_VARIABLE_STRUCT g_logger;

 
 /* Handles for operating the LEDs LED(1:2),SW(1:2) and ADCs. */
 /* Ref: Freescale MQX I/O Drivers Users Guide (MQXIOUG.pdf). Chapter 7 */
 
 FILE_PTR led_file1, led_file2, led_file3, sw_file, result_file; 
 FILE_PTR adc_file1, adc_file2, adc_file3;
 
 /*
  *	Arrays for operating the LEDs and switches.
  */
 
 /* LED Arrays */
 
 /* Declare arrays of type 
 	GPIO_PIN_STRUCT (...\lib\m52259demo.cw\mqx\io_gpio.h) 
 		which define the LED pins in the format 
   		<port_name> | <pin_number> | <additional_flage>.
 	Ref: MQX I/O User's Guide "7.5 Opening GPIO Device"
  */
 
 /* Define an array listing all the LEDs. It will be used to open
 		a GPIO device driver for controlling the LEDs. */
 GPIO_PIN_STRUCT pins1[] = 
 {
 	/* Open file to control LEDs(1:2) and initialise their status to OFF.
 		Here <additional_flags> = GPIO_PIN_STATUS_0 will clear the pin. */
 	BSP_LED1 | GPIO_PIN_STATUS_0,	// 
 	BSP_LED2 | GPIO_PIN_STATUS_0,
 	BSP_LED3 | GPIO_PIN_STATUS_0,
 	BSP_LED4 | GPIO_PIN_STATUS_0,
 	GPIO_LIST_END
 };
 
 /* Define arrays for writing to the LEDs individually.
 	These are used with the Generic IOCTL Commands. */
 
 /* For controlling LED1 individually */
  GPIO_PIN_STRUCT pins2[] = 
 {
 	BSP_LED1,
 	GPIO_LIST_END
 };
 
 /* For controlling LED2 individually */
  GPIO_PIN_STRUCT pins3[] = 
 {
 	BSP_LED2,
 	GPIO_LIST_END
 };
 
 /* For controlling LED3 individually */
  GPIO_PIN_STRUCT pins4[] = 
 {
 	BSP_LED3,
 	GPIO_LIST_END
 };
 
 /* For controlling LED4 individually */
  GPIO_PIN_STRUCT pins5[] = 
 {
 	BSP_LED4,
 	GPIO_LIST_END
 };
 
 
 /* Define an array listing all the Switches. It will be used to open
 		a GPIO device driver for controlling the Switches. */
 GPIO_PIN_STRUCT pins6[] =
 {
 	BSP_BUTTON1 | GPIO_PIN_IRQ_FALLING,	// Interrupt on falling edge
 	BSP_BUTTON2 | GPIO_PIN_IRQ_FALLING,
 	GPIO_LIST_END
 };
 
 
 /* 
  * For controlling the Analog-To-Digital Converter. 
  */
 
 /* ADC device init struct */
 const ADC_INIT_STRUCT adc_init = {
    ADC_RESOLUTION_DEFAULT,     /* resolution */
 };
 
 /* Using AN0 - M52259DEMOCOM connector J4 pin 29. */
 /* Sampling will be initiated upon receipt of these parameters. */
 /* Once triggered samples continuously at 1kHz. */
const ADC_INIT_CHANNEL_STRUCT adc_channel_param0 = 
{
    ADC_SOURCE_AN0, /* Using ADC channel 0 */
    /* Sample one sequence only, immediatly upon receipt of a trigger. */
    ADC_CHANNEL_MEASURE_LOOP | ADC_CHANNEL_START_TRIGGERED, 
    1,              /* number of samples in one run sequence */
    0,         		/* time offset from trigger point in us */
    1000,         	/* period in us (= 0.001 sec) */
    0x10000,        /* scale range of result (not used now) */
    1,              /* circular buffer size (sample count) */
    MY_TRIGGER_0,   /* logical trigger ID that starts this ADC channel */
#if MQX_USE_LWEVENTS
    NULL
#endif
};


 /* Using AN1 - M52259DEMOCOM connector J4 pin 30. */
 /* Sampling will be initiated upon receipt of these parameters. */
 /* Once triggered samples continuously at 1kHz. */
const ADC_INIT_CHANNEL_STRUCT adc_channel_param1 = 
{
    ADC_SOURCE_AN1, /* Using ADC channel 1 */
    /* Sample one sequence only, immediatly upon receipt of a trigger. */
    ADC_CHANNEL_MEASURE_LOOP | ADC_CHANNEL_START_TRIGGERED, 
    1,              /* number of samples in one run sequence */
    0,         		/* time offset from trigger point in us */
    1000,         	/* period in us (= 0.001 sec) */
    0x10000,        /* scale range of result (not used now) */
    1,              /* circular buffer size (sample count) */
    MY_TRIGGER_1,   /* logical trigger ID that starts this ADC channel */
#if MQX_USE_LWEVENTS
    NULL
#endif
};

uint_8 adc_triggered = 0;




/******************************************************************************
 *  
 *   @name        TestApp_Init
 * 
 *   @brief       This function is the entry for USB Logger (or other usuage)
 * 
 *   @param       None
 * 
 *   @return      None
 *               
 *****************************************************************************/
void TestApp_Init(void)
{       
    
    USB_Class_LOGGER_Init();
    
    /* Initialise the endpoint control structure */
    Endpoint_Init();
    

    /* Initialise control of LED(1:2) */
    LED_1_4_Init();
    
    /* Wait loop */
    while (TRUE)
    {
    	/* Check for the arrival of a packet at EP1 or EP3 */
    	EP3_PACKET_REC();
    	
    	/* Repeat every 10mSec. */
    	
    	
    	if(LChase)
    	{
	    	ioctl(led_file1, GPIO_IOCTL_WRITE_LOG0, &pins2);
	    	ioctl(led_file1, GPIO_IOCTL_WRITE_LOG1, &pins3);
	   		 _time_delay(10);
	    	EP3_PACKET_REC();
    	}
		if(LChase)
		{
	    	ioctl(led_file1, GPIO_IOCTL_WRITE_LOG0, &pins3);
	    	ioctl(led_file1, GPIO_IOCTL_WRITE_LOG1, &pins4);
	  		_time_delay(10);
	  		EP3_PACKET_REC();
		}
		if(LChase)	
	   	{
	   	 	ioctl(led_file1, GPIO_IOCTL_WRITE_LOG0, &pins4);
	    	ioctl(led_file1, GPIO_IOCTL_WRITE_LOG1, &pins5);
	   		 _time_delay(10);
	   		EP3_PACKET_REC();
	   	}
	   	if(LChase)	
	   	{
	    	ioctl(led_file1, GPIO_IOCTL_WRITE_LOG0, &pins5);
	    	ioctl(led_file1, GPIO_IOCTL_WRITE_LOG1, &pins2);
	   		 _time_delay(10);
    	}

				    	
    }
  
} 
 
 
/****************************************************************************
 *
 * Function Name  : Endpoint_Init
 * Returned Value : None
 *
 * Operation	  : Initialises the structures for controlling 
 *                   endpoint transactions.
 *					Structures store data packets received at OUT endpoints.
 *
 ***************************************************************************/
 void Endpoint_Init(void)
 {
 	
 	EP_RX_CTRL_PTR epctrlPtr;		// Pointer to an EP control structure
 	
 	/* Initialise EP1 structure */
 	epctrlPtr = &ep1_rx_ctrl;		// Set the pointer to the EP1 control structure
 	epctrlPtr->pkt_rec = FALSE;	// Clear packet received flag
 	epctrlPtr->overrun_err = FALSE;	// Clear overrun error flag
 	epctrlPtr->len = 0x00;				// Received packet length zero
 	
 	/* Initialise EP3 structure */
 	epctrlPtr = &ep3_rx_ctrl;		// Set the pointer to the EP3 control structure
 	epctrlPtr->pkt_rec = FALSE;	// Clear packet received flag
 	epctrlPtr->overrun_err = FALSE;	// Clear overrun error flag
 	epctrlPtr->len = 0x00;				// Received packet length zero
 	
 	
 }
 
 /****************************************************************************
 *
 * Function Name  : LED_1_4_Init
 * Returned Value : None
 *
 *	Operation:		Open a GPIO device for writing to the LEDs.
 *					Specify the pins to be used (BSP_LED1:BSP_LED4)
 *						and the pin direction (OUT - write).
 *					Open a GPIO device for reading the switches SW1 & SW2.
 *					Specify the pins to be used (BSP_BUTTON1, BSP_BUTTON2)
 *						and the pin direction (IN - read).
 * 					Each open operation returns a handle to the GPIO device.
 *
 ***************************************************************************/
 
 void LED_1_4_Init()
 {
 	/* Open a GPIO device for writing to the LEDs */
 	led_file1 = fopen("gpio:write", (char_ptr) &pins1);
 	led_file2 = fopen("gpio:read", (char_ptr) &pins1);
 	
 	/* Open a GPIO device for reading the switches. */
 	sw_file = fopen("gpio:read", (char_ptr) &pins6);
 	
 	/* Switches are programmed to generate an interrupt off the falling edge
 		when they are pressed */
 	/* Specify <handle>, <operation>, <interrupt service routine> */
 	ioctl(sw_file, GPIO_IOCTL_SET_IRQ_FUNCTION, Switch_Read);	
 	ioctl(sw_file, GPIO_IOCTL_ENABLE_IRQ, NULL);	// Enable the interrupt.
 }
 
 
 
//*********************** Functions ****************************************
 
/****************************************************************************
 *
 * Function Name  : LEDSOFF & LEDSON
 * Returned Value : None
 *
 * Operation	  : 
 *
 ***************************************************************************/
void LEDSOFF(void)
{
		ioctl(led_file1, GPIO_IOCTL_WRITE_LOG0, &pins2);
 		ioctl(led_file1, GPIO_IOCTL_WRITE_LOG0, &pins3);
 		ioctl(led_file1, GPIO_IOCTL_WRITE_LOG0, &pins4);
 		ioctl(led_file1, GPIO_IOCTL_WRITE_LOG0, &pins5);
};

void LEDSON(void)
{
		ioctl(led_file1, GPIO_IOCTL_WRITE_LOG1, &pins2);
 		ioctl(led_file1, GPIO_IOCTL_WRITE_LOG1, &pins3);
 		ioctl(led_file1, GPIO_IOCTL_WRITE_LOG1, &pins4);
 		ioctl(led_file1, GPIO_IOCTL_WRITE_LOG1, &pins5);
};
	
/****************************************************************************
 *
 * Function Name  : Switch_Read
 * Returned Value : None
 *
 * Operation	  : Callback function called as an interrupt service routine 
 *                   when a switch is pressed.
 *					Determines which switch was pressed (SW1 or SW2) and
 *						Sends the information to the host.
 *
 ***************************************************************************/
 
 void Switch_Read(void)
 {
 int i;
 	
 	/* Determine which switch has been pressed*/
 	
 ioctl(sw_file, GPIO_IOCTL_READ, &pins6);	// Read the switch status.
 
	if((pins6[0] & GPIO_PIN_STATUS) == 1)    // SW2 pressed? Turn off LED's 1 and 2
 	{
 	
 
 	}
 	

 	if((pins6[1] & GPIO_PIN_STATUS) == 1)	// SW1 pressed? Induce Error of +1 into Data for each press
	{
 		for(i = 0; i < 	Putter; i++)
 			{
 				Data[i]++;
 			}	
	}
 }
 

/****************************************************************************
 *
 * Function Name  : EP3_PACKET_REC()
 * Returned Value : None
 *
 * Operation	  : Checks for the arrival of a packet at EPn where n(1,3)
 *						and processes received packets.
 *					The  structures ep1_rx_ctrl and ep3_rx_ctrl (declared in
 *						usb_logger.c) are used for controlling packet
 *						reception.
 *					The arrival of a packet is indicated 
 *						by the flag epn_rx_ctrl.pkt_rec.
 *					Received packets are transferred to the 
 *						receive packet buffer epn_rx_ctrl.ep_pkt_buf[].
 *					The size of a received packet is indicated by
 *						epn_rx_ctrl.len.
 *                   
 *
 ***************************************************************************/
 void EP3_PACKET_REC(void)
 {
 	uint_32 count; 
 	uint_32 command;
    uint_32 byte_count;	
    uint_32 TxSize;		
    //uint_32 RxSize;
 	EP_RX_CTRL_PTR ep3ctrlPtr;		// Pointer for an EP3 control structure
 	
 	ep3ctrlPtr = &ep3_rx_ctrl;		// Set the pointer to the EP3 control structure
 	
 
  	/* Check for an EP3 received packet */
 	if(ep3ctrlPtr->pkt_rec == TRUE)	
 	{
 		/* EP3 packet has arrived */
 		/* Transfer the packet to the EP3 receive packet buffer ep_pht_buf[]. */
 		byte_count = ep3ctrlPtr->len;	// Packet size
 		for(count = 0; count < ep3ctrlPtr->len; count++)
 		{
 			ep3ctrlPtr->ep_pkt_buf[count] = *ep3ctrlPtr->buffer_ptr++;
 		}
 		
 		/* Clear packet received flag */
 		ep3ctrlPtr->pkt_rec = FALSE;
 		
 		/* Check for an overrun error */
 		if(ep3ctrlPtr->overrun_err == TRUE)
 		{
 			/* Ignore for now. */
 			ep3ctrlPtr->overrun_err = FALSE;
 		}
 		
 		
 		/* Process the EP3 command: EP3 controls Data In/Out*/
 		// Command is the first byte 
 		// Size of data request is second byte
 		
 		command = ep3ctrlPtr->ep_pkt_buf[0];
 		
 		switch(command)
 		{
 			
 			case Rx_Data:	
 			// Recieve data via EP3
 			//RxSize = ep3ctrlPtr->ep_pkt_buf[1];
 			Data_Length = ep3ctrlPtr->len;	
 			
 			// Loop InBuffer into Data (Ring Buffer)
 			for(count = 2; count < 	Data_Length; count++)
 				{
 					Data[Putter] = ep3ctrlPtr->ep_pkt_buf[count];
 					Putter++;
 					if(Putter > 14999)	//End of Buffer => return to start
 					{
 						Putter = 0;		
 					}
 				}		
 	  		break;	
 	  		
 	  		
 	  		case Tx_Data:
 			// Transmit data via EP3
 			// Size of data transfer is second byte of command
 			TxSize = ep3ctrlPtr->ep_pkt_buf[1];
 			
 			// Loop Data into OutBffer 
 			count = 0;
 				do
 				{
 					g_logger.rpt_buf[count] = Data[Getter]; 
 					count++;
 					Getter++;
 					if(Getter > 14999)	//End of Buffer => return to start
 					{
 						Getter = 0;		
 					}
 				} while(Getter != Putter && count < TxSize);
 								
 			(void)USB_Class_EP4_Send_Data(USB_EP4, g_logger.rpt_buf,TxSize); 
 			break;
 			
 				
 			case Leds_On:		// All Leds on
 				LChase = 0;
				LEDSON();
 			
 			break;
 			
 			case Leds_Off:		// All LEDs off
 				LChase = 0;
 				LEDSOFF();
 			break;
 			
 			case Leds_Chase: // All Led chase mode
 				LChase = 1;
 				LEDSOFF();
 			break;
 			
 			case Reset_Data:		// Reset MCU State
 				Putter = 0;		    //Data vector putter
				Getter = 0;	     	//Data vector getter
  				i = 0;				//General loop index  
  				Data_Length = 0;	//Data vector length
  				
  				// Reset data array
  				for(count = 0; count < 15000; count++)
  				{
  					Data[count] = 0;
  				}
  									
 				
 			break;
 	}
	
 }

 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 